package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @author Harry hou
 * @date 2019/11/18 10:26
 */
@Slf4j
@Service(value = "PRIORITY_POINT_RULE")
public class PriorityRuleInterceptor extends GradeRuleInterceptorAdapter {

    private static final String PRIORITY = "priority";
    private List<PriorityRulesParams> priorityRulesParams;

    @Override
    public void prepare(TicketRule rule) {
        this.priorityRulesParams = this.objectMapper.convertValue(rule.getParams(), new TypeReference<>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        int order = 0;
        if (!StringUtils.isEmpty(ticket.getPriorityId())) {
            Integer priorityId = ticket.getPriorityId();
            order = priorityRulesParams.stream().filter(item -> item.selected && item.getPriorityId().equals(priorityId))
                    .mapToInt(PriorityRulesParams::getPoints).sum();
        }
        JsonNode jsonNode = ticket.getOrderDetail() == null ? objectMapper.createObjectNode() : ticket.getOrderDetail();

        ObjectNode jsonNodeParams = objectMapper.createObjectNode();
        jsonNodeParams.put("priorityId", ticket.getPriorityId());
        jsonNodeParams.put("priorityName", ticket.getPriorityName());
        jsonNodeParams.put("point", order);
        ObjectNode objectNode = jsonNode.deepCopy();
        objectNode.set(PRIORITY, jsonNodeParams);
        ticket.setOrderDetail(objectNode);
        ticket.setOrder(ticket.getOrder() + order);
    }

    @Data
    private static class PriorityRulesParams {
        private Integer priorityId;
        private Integer points;
        private boolean selected;
    }

}
